#include <gtkmm.h>

class MyWindow : public Gtk::Window {
public:
    MyWindow() {
        set_title("GtkTextView Example");  // 设置窗口标题
        set_default_size(400, 300);  // 设置窗口默认大小

        Gtk::Box* vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL, 10));  // 创建垂直盒子容器
        add(*vbox);  // 将盒子容器添加到窗口

        Gtk::ScrolledWindow* scrolled_window = Gtk::manage(new Gtk::ScrolledWindow());  // 创建滚动窗口控件
        scrolled_window->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);  // 设置滚动策略

        text_view = Gtk::manage(new Gtk::TextView());  // 创建文本视图控件
        text_buffer = Gtk::TextBuffer::create();  // 创建文本缓冲区
        text_view->set_buffer(text_buffer);  // 将文本缓冲区设置到文本视图中

        scrolled_window->add(*text_view);  // 将文本视图添加到滚动窗口中
        vbox->pack_start(*scrolled_window);  // 将滚动窗口添加到盒子容器中

        label = Gtk::manage(new Gtk::Label());  // 创建标签控件
        vbox->pack_start(*label);  // 将标签添加到盒子容器中

        // 连接文本缓冲区文本变化事件的信号处理函数
        text_buffer->signal_changed().connect(sigc::mem_fun(*this, &MyWindow::on_text_changed));

        show_all_children();  // 显示所有子控件
    }

    virtual ~MyWindow() {}

protected:
    // 文本缓冲区文本变化事件处理函数
    void on_text_changed() {
        Glib::ustring text = text_buffer->get_text();  // 获取文本缓冲区的当前文本内容
        label->set_text("Text length: " + std::to_string(text.length()));  // 根据输入内容更新标签，显示文本长度
    }

    Gtk::TextView* text_view;  // 文本视图控件指针
    Glib::RefPtr<Gtk::TextBuffer> text_buffer;  // 文本缓冲区对象
    Gtk::Label* label;  // 标签控件指针
};

int main(int argc, char *argv[]) {
    auto app = Gtk::Application::create(argc, argv, "com.example.GtkTextViewExample");  // 创建 GTK 应用程序实例

    MyWindow window;  // 创建主窗口实例

    return app->run(window);  // 运行应用程序
}

